package cn.codeartist.springboot.component.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.Consumer;

/**
 * 对象工具类
 *
 * @author 艾江南
 * @date 2019/6/5
 */
public final class BeanUtil {

    private final static Logger logger = LoggerFactory.getLogger(BeanUtil.class);

    /**
     * 类复制
     *
     * @param source 源类
     * @param target 目标类
     */
    public static void copy(Object source, Object target) {
        BeanUtils.copyProperties(source, target);
    }

    /**
     * 类复制
     *
     * @param source      源类
     * @param targetClass 目标类类型
     * @param <T>         目标类泛型
     * @return 目标类
     */
    public static <T> T copy(Object source, Class<T> targetClass) {
        try {
            T t = BeanUtils.instantiateClass(targetClass);
            copy(source, t);
            return t;
        } catch (Exception e) {
            logger.error("类型转换异常", e);
        }
        return null;
    }

    /**
     * 类复制
     *
     * @param source      源类
     * @param targetClass 目标类类型
     * @param <T>         目标类泛型
     * @return 目标类列表
     */
    public static <T> List<T> copy(Collection<?> source, Class<T> targetClass) {
        List<T> list = new ArrayList<>();
        if (source == null || source.isEmpty()) {
            return list;
        }
        for (Object s : source) {
            T map = copy(s, targetClass);
            list.add(map);
        }
        return list;
    }


    /**
     * 类复制
     *
     * @param <T>         目标类泛型
     * @param source      源类
     * @param targetClass 目标类类型
     * @param mapConsumer 映射操作
     * @return 目标类列表
     */
    public static <T> List<T> copy(Collection<?> source, Class<T> targetClass, Consumer<T> mapConsumer) {
        List<T> list = new ArrayList<>();
        if (source == null || source.isEmpty()) {
            return list;
        }
        for (Object s : source) {
            T map = copy(s, targetClass);
            mapConsumer.accept(map);
            list.add(map);
        }
        return list;
    }

    /**
     * 类复制
     *
     * @param <T>         目标类泛型
     * @param source      源类
     * @param targetClass 目标类类型
     * @param mapConsumer 映射操作
     * @return 目标类列表
     */
    public static <S, T> List<T> copy(Collection<S> source, Class<T> targetClass, BiConsumer<S, T> mapConsumer) {
        List<T> list = new ArrayList<>();
        if (source == null || source.isEmpty()) {
            return list;
        }
        for (S s : source) {
            T map = copy(s, targetClass);
            mapConsumer.accept(s, map);
            list.add(map);
        }
        return list;
    }
}
